View Javadoc

1   /*
2    * Created on 19-Dec-2004
3    */
4   package uk.ac.roe.antigen.ant;
5   
6   import java.io.BufferedInputStream;
7   import java.io.File;
8   import java.io.FileOutputStream;
9   import java.io.IOException;
10  import java.io.InputStream;
11  import java.io.OutputStream;
12  import java.io.BufferedOutputStream;
13  import java.net.JarURLConnection;
14  import java.net.URL;
15  import java.util.Enumeration;
16  import java.util.jar.JarEntry;
17  import java.util.jar.JarFile;
18  import java.util.logging.Logger;
19  
20  import uk.ac.roe.antigen.utils.CopyableFile;
21  
22  
23  /***
24   * Grabs a directory, or a zip file, and installs it in the temp directory for
25   * processing
26   * 
27   * @author jdt
28   *  
29   */
30  public class BuildGrabber {
31      /***
32       * Logger for this class
33       */
34      private static final Logger logger = Logger.getLogger(BuildGrabber.class.getName());
35  
36  
37  	private CopyableFile tmpDir;
38  
39  	public static void main(String[] args) throws Exception {
40  		BuildGrabber grabber = new BuildGrabber();
41  		try {
42  			CopyableFile tmp = grabber.tmpDir;
43  			logger.fine("Temporary directory: " + tmp);
44  			//File testDir = new File("C:/Java/ag-integration-work");
45  			URL jarUrl = new URL(
46  					"file:///C:/Documents and Settings/jdt/.maven/repository/org.astrogrid/wars/astrogrid-portal-0.7-b015p.war");
47  			//File copiedDir = grabber.grab(jarUrl);
48  			File copiedDir = grabber.grab("/foo");
49  			logger.fine("Copied dir was " + copiedDir);
50  			Thread.sleep(30000);
51  		} finally {
52  			System.out.println("Deleted? " + grabber.deleteTmp());
53  		}
54  	}
55  
56  	/***
57  	 * Source files are supplied as a known directory
58  	 * 
59  	 * @param dir
60  	 * @throws IOException
61  	 * @return the tmp directory holding the files
62  	 */
63  	public CopyableFile grab(File dir) throws IOException {
64  		new CopyableFile(dir).copyTo(tmpDir);
65  		return tmpDir;
66  	}
67  
68  	/***
69  	 * Grabs contents of a jar file from a URL and unzip to a temp directory
70  	 * 
71  	 * @param url
72  	 *            of jar file
73  	 * @return the tmp directory holding the files
74  	 * @throws IOException
75  	 */
76  	public CopyableFile grab(URL url) throws IOException {
77  		String simpleUrl = url.toExternalForm();
78  		logger.fine("Grabbing from " + simpleUrl);
79  		JarURLConnection jarUrl = (JarURLConnection) new URL("jar:" + simpleUrl
80  				+ "!/").openConnection();
81  		logger.fine("Opening connection to " + jarUrl);
82  		JarFile jarFile = jarUrl.getJarFile();
83  		return grab(jarFile);
84  	}
85  
86  	/***
87  	 * Grab the contents of a jar file and unzip to a temp directory
88  	 * 
89  	 * @param jar
90  	 *            the jar file
91  	 * @return the tmp directory holding the files
92  	 * @throws IOException
93  	 * @TODO factor this out into separate class
94  	 */
95  	public CopyableFile grab(JarFile jar) throws IOException {
96  		Enumeration entries = jar.entries();
97  		while (entries.hasMoreElements()) {
98  			JarEntry entry = (JarEntry) entries.nextElement();
99  			logger.fine("Entry " + entry);
100 
101 			File copiedFileEntry = new File(tmpDir, entry.getName());
102 			logger.fine("Copying to " + copiedFileEntry.getAbsolutePath());
103 
104 			if (entry.isDirectory()) {
105 				copiedFileEntry.mkdirs();
106 			} else {
107 				InputStream is = new BufferedInputStream(jar
108 						.getInputStream(entry));
109 				copiedFileEntry.createNewFile();
110 				FileOutputStream os = new FileOutputStream(copiedFileEntry);
111 
112 				copyStreams(is, os);
113 			}
114 
115 		}
116 		return tmpDir;
117 	}
118 
119 	private void copyStreams(InputStream in, OutputStream out)
120 			throws IOException {
121 		int data = -1;
122 		while ((data = in.read()) != -1) {
123 			out.write(data);
124 		}
125 		out.close();
126 
127 		in.close();
128 	}
129 
130 	/***
131 	 * Grabs stuff off the classpath and stick it in the temp directory
132 	 * 
133 	 * @param path
134 	 *            the path off the classpath to the jar
135 	 * @return the temp directory in which the grabbed stuff has been stuck
136 	 * @throws IOException
137 	 */
138 	public CopyableFile grab(String path) throws IOException {
139         // Since this has been reimplemented, it only deals with 
140         // paths that are absolute off the classpath, so any initial
141         // slash must be dropped.
142         if (path.startsWith("/")) {
143             path = path.substring(1);
144         }
145 		File tmpJarFile = File.createTempFile("build", ".jar");
146 		tmpJarFile.deleteOnExit();
147                 JarFile installSource = new JarFile(System.getProperty("java.class.path"));
148                 logger.fine("path: "+path);
149                 File antBuildJar = unzipFile(path,installSource, tmpDir, false);
150 
151 		JarFile jar = new JarFile(antBuildJar);
152                 unzipFile(null,jar,tmpDir,true);
153 
154 		return tmpDir;
155 
156 	}
157 
158     /***
159      * Unzips either one file specified by fullPathFileName or all files (if fullPathFileName is null) from srcJar to destDir
160      * @param fullPathFileName
161      * @param srcJar
162      * @param destDir
163      * @return if fullPathFileName is not null then returns the unzipped file, otherwise returns null
164      */
165     private File unzipFile(String fullPathFileName, JarFile srcJar, File destDir, boolean useFullPath) {
166        int BUFFER = 16384;
167        BufferedOutputStream dest = null;
168        BufferedInputStream is = null;
169        JarEntry entry;
170        String newFullPathFileName = null;
171        Enumeration e = srcJar.entries();
172         try {
173            while(e.hasMoreElements()) {
174                entry = (JarEntry) e.nextElement();
175                if (fullPathFileName != null && !(entry.getName().equals(fullPathFileName) )) {
176                    continue;
177                }
178 
179                logger.fine("Extracting: " +entry);
180                is = new BufferedInputStream(srcJar.getInputStream(entry));
181                 int count;
182                 byte data[] = new byte[BUFFER];
183                int lastIndexOfSlashPlusOne = entry.getName().lastIndexOf('/')+1;
184                String path = null;
185                String fileName = null;
186                if (lastIndexOfSlashPlusOne == 0) {
187                    path = "";
188                } else {
189                    path = entry.getName().substring(0,lastIndexOfSlashPlusOne);
190                    String sep = File.separator;
191                    if (sep.equals("//")) {
192                        sep = "////";
193                    }
194                    path = path.replaceAll("/",sep);
195                }
196                fileName = entry.getName().substring(lastIndexOfSlashPlusOne);
197                String newEntryName = destDir.getAbsolutePath()+File.separator+path+fileName;
198                if (!useFullPath) {
199                    newEntryName = destDir.getAbsolutePath()+File.separator+fileName;
200                }
201                if (entry.isDirectory()) {
202                    File entryFile = new File(newEntryName);
203                    if (!entryFile.exists()) {
204                        entryFile.mkdirs();
205                    }
206                    continue;
207                }
208                newFullPathFileName = newEntryName;
209 
210                 FileOutputStream fos = new FileOutputStream(newFullPathFileName);
211                 dest = new
212                   BufferedOutputStream(fos, BUFFER);
213                 while ((count = is.read(data, 0, BUFFER)) != -1) {
214                    dest.write(data, 0, count);
215                 }
216                 dest.flush();
217                 dest.close();
218                 is.close();
219                if (fullPathFileName != null) {
220                     return new File(newFullPathFileName);
221                 }
222              }
223          } catch(Exception ex) {
224             logger.warning(ex.getMessage());
225             ex.printStackTrace();
226          }
227 
228         return null;
229     }
230 
231     /***
232 	 * On the off chance that the system doesn't delete it, you can try to
233 	 * delete it yourself
234 	 * 
235 	 * @return true or false depending on success
236 	 */
237 	public boolean deleteTmp() {
238 
239 		return tmpDir.recursivelyDelete();
240 	}
241 
242 	/***
243 	 * Set up temp directories etc
244 	 * 
245 	 * @throws IOException
246 	 *  
247 	 */
248 	public BuildGrabber() throws IOException {
249 		String systemTemp = System.getProperty("java.io.tmpdir");
250 		logger.fine("System Temp Dir " + systemTemp);
251 
252 		tmpDir = new CopyableFile(File.createTempFile("antigen", "", new File(
253 				systemTemp)));
254         logger.info("Build Dir " + tmpDir);
255 		//Delete any existing file
256 		tmpDir.delete();
257 		tmpDir.mkdirs();
258 		tmpDir.deleteOnExit();
259 	}
260     /***
261      * Set up temp directories etc
262      * User-supplied tmpdirectory
263      * 
264      * @throws IOException
265      *  
266      */
267     public BuildGrabber(File dir) throws IOException {
268         tmpDir = new CopyableFile(dir);
269         logger.info("Build Dir " + tmpDir);
270     }
271 }